Refactor Drop classes.

Not alone EventDrop but all subclasses now take a hash of "locals" which
could be referenced in interpolation. This will make it easier for
Agent classes to add custom "locals" for use in interpolation.

Akinori MUSHA 10 years ago
parent
commit
a93bb2674e
4 changed files with 65 additions and 30 deletions
  1. 42 1
      app/concerns/liquid_droppable.rb
  2. 2 12
      app/models/agent.rb
  3. 12 17
      app/models/event.rb
  4. 9 0
      spec/models/event_spec.rb

+ 42 - 1
app/concerns/liquid_droppable.rb

@@ -1,9 +1,50 @@
1 1
 module LiquidDroppable
2 2
   extend ActiveSupport::Concern
3 3
 
4
+  # In subclasses of this base class, "locals" take precedence over
5
+  # methods.
4 6
   class Drop < Liquid::Drop
5
-    def initialize(object)
7
+    class << self
8
+      def inherited(subclass)
9
+        class << subclass
10
+          attr_reader :drop_methods
11
+
12
+          # Make all public methods private so that #before_method
13
+          # catches everything.
14
+          def drop_methods!
15
+            return if @drop_methods
16
+
17
+            @drop_methods = Set.new
18
+
19
+            (public_instance_methods - Drop.public_instance_methods).each { |name|
20
+              @drop_methods << name.to_s
21
+              private name
22
+            }
23
+          end
24
+        end
25
+      end
26
+    end
27
+
28
+    def initialize(object, locals = nil)
29
+      self.class.drop_methods!
30
+
6 31
       @object = object
32
+      @locals = locals || {}
33
+    end
34
+
35
+    def before_method(name)
36
+      if @locals.include?(name)
37
+        @locals[name]
38
+      elsif self.class.drop_methods.include?(name)
39
+        __send__(name)
40
+      end
41
+    end
42
+
43
+    def each
44
+      return to_enum(__method__) unless block_given?
45
+      self.class.drop_methods.each { |name|
46
+        yield [name, __send__(name)]
47
+      }
7 48
     end
8 49
   end
9 50
 

+ 2 - 12
app/models/agent.rb

@@ -391,7 +391,7 @@ class AgentDrop
391 391
     @object.short_type
392 392
   end
393 393
 
394
-  METHODS = [
394
+  [
395 395
     :name,
396 396
     :type,
397 397
     :options,
@@ -402,19 +402,9 @@ class AgentDrop
402 402
     :disabled,
403 403
     :keep_events_for,
404 404
     :propagate_immediately,
405
-  ]
406
-
407
-  METHODS.each { |attr|
405
+  ].each { |attr|
408 406
     define_method(attr) {
409 407
       @object.__send__(attr)
410 408
     } unless method_defined?(attr)
411 409
   }
412
-
413
-  def each(&block)
414
-    return to_enum(__method__) unless block
415
-
416
-    METHODS.each { |attr|
417
-      yield [attr, __sent__(attr)]
418
-    }
419
-  end
420 410
 end

+ 12 - 17
app/models/event.rb

@@ -44,26 +44,21 @@ class Event < ActiveRecord::Base
44 44
 end
45 45
 
46 46
 class EventDrop
47
-  def initialize(event, payload = event.payload)
48
-    super(event)
49
-    @payload = payload
50
-  end
51
-
52
-  def before_method(key)
53
-    if @payload.key?(key)
54
-      @payload[key]
55
-    else
56
-      case key
57
-      when 'agent'
58
-        @object.agent
59
-      when 'created_at'
60
-        @object.created_at
61
-      end
62
-    end
47
+  def initialize(object, locals = nil)
48
+    locals ||= object.payload
49
+    super
63 50
   end
64 51
 
65 52
   def each(&block)
66 53
     return to_enum(__method__) unless block
67
-    @payload.each(&block)
54
+    @locals.each(&block)
55
+  end
56
+
57
+  def agent
58
+    @object.agent
59
+  end
60
+
61
+  def created_at
62
+    @object.created_at
68 63
   end
69 64
 end

+ 9 - 0
spec/models/event_spec.rb

@@ -102,6 +102,15 @@ describe EventDrop do
102 102
     interpolate(t, @event).should eq('some title: http://some.site.example.org/')
103 103
   end
104 104
 
105
+  it 'should use created_at from the payload if it exists' do
106
+    created_at = @event.created_at - 86400
107
+    # Avoid timezone issue by using %s
108
+    @event.payload['created_at'] = created_at.strftime("%s")
109
+    @event.save!
110
+    t = '{{created_at | date:"%s" }}'
111
+    interpolate(t, @event).should eq(created_at.strftime("%s"))
112
+  end
113
+
105 114
   it 'should be iteratable' do
106 115
     # to_liquid returns self
107 116
     t = "{% for pair in to_liquid %}{{pair | join:':' }}\n{% endfor %}"